package com.ddd.codegeneration.serviceImpl;

import com.ddd.codegeneration.entity.entity.Attribute;
import com.ddd.codegeneration.entity.entity.Column;
import com.ddd.codegeneration.entity.entity.EntityParameter;
import com.ddd.codegeneration.service.CodeGenerationService;
import com.ddd.codegeneration.service.GeneratorBackEndService;
import com.ddd.codegeneration.service.GeneratorBaseCodeService;
import com.ddd.codegeneration.utils.FormatDate;
import com.ddd.codegeneration.utils.FreeMarkerConfigUtils;
import com.ddd.codegeneration.utils.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author 官江涛
 * @version 1.0
 * @Title:   代码生成实体
 * @date 2018/7/22/22:22
 */
@Component
@Transactional
public class CodeGenerationServiceImpl implements CodeGenerationService{

    @Autowired
    private GeneratorBackEndService generatorBackEndService;
    @Autowired
    private GeneratorBaseCodeService generatorBaseCodeService;

//    public CodeGenerationServiceImpl(){
//        generatorBackEndService = new GeneratorBackEndServiceImpl();
//        generatorBaseCodeService = new GeneratorBaseCodeServiceImpl();
//    }

    /**
     * 后台代码生成
     * @param entityParameter 前台接收到的实体
     * @return  成功 -----> 对应类的类路径，失败 ------> null
     */
    @Override
    public String generateJavaCode(EntityParameter entityParameter) {
        // 获取配置文件信息
        HashMap config = FreeMarkerConfigUtils.getConfig("templateConfig.yml");

        HashMap javaConfig = (HashMap) ((HashMap) config.get("generator")).get("java");

        HashMap javaCode = (HashMap) javaConfig.get("code");

        HashMap javaCodePackage = (HashMap) javaConfig.get("package");

        // 数据预处理
        Map<String, Object> root = new HashMap<String, Object>();
        String className = entityParameter.fristWordToUpperCase(entityParameter.getEntityName());
        root.put("entityPackageName", javaCodePackage.get("entityPackage").toString());
        root.put("servicePackageName", javaCodePackage.get("servicePackage").toString());
        root.put("serviceImplPackageName",javaCodePackage.get("serviceImplPackage").toString());
        root.put("controllerPackageName",javaCodePackage.get("controllerPackage").toString());
        root.put("mapperPackageName",javaCodePackage.get("mapperPackage").toString());
        root.put("className", className);
        root.put("author", "官江涛");
        root.put("date", Utils.typeThree(new Date()));
        List<Attribute> attr_list = new ArrayList<Attribute>();
        for (Column column : entityParameter.getColumns()){
            attr_list.add(new Attribute(column.getColumName(), column.getColumType()));
        }
        String columnsToString = getColumnsToString(attr_list);
        root.put("attrs", attr_list);
        root.put("columns",columnsToString);
        // 生成Entity
        String entityURL = generatorBackEndService.generateEntity(root,javaCode.get("entityPath").toString());
        // 生成service代码
        generatorBackEndService.generateService(root,javaCode.get("servicePath").toString());
        // 生成Controller代码
        generatorBackEndService.generateController(root,javaCode.get("controllerPath").toString());
        //  生成serviceImpl代码
        generatorBackEndService.generateServiceImpl(root,javaCode.get("serviceImplPath").toString());
        //  生成javaMapper代码
        generatorBackEndService.generateJavaMapper(root,javaCode.get("mapperPath").toString());
        // 生成XMLMapper代码
        generatorBackEndService.generateXMLMapper(root,javaCode.get("xmlPath").toString());
        return entityURL;
    }

    /**
     * 前台代码生成
     * @param entityUrl   实体的类全名
     * @return      true or false
     */
    @Override
    public boolean generateBaseCode(String entityUrl) {
        // 获取实体对应的类型+字段
        HashMap getEntities = getEntities(entityUrl);
        Map<String, Object> root = new HashMap<String, Object>();
        String className = getClassName(entityUrl);
        root.put("className", className);
        root.put("author", "官江涛");
        root.put("date", Utils.typeThree(new Date()));
        String savePath = "D://";
        // 生成Eapi
        generatorBaseCodeService.generateApi(root,savePath);

        return false;
    }

    /**
     *  获取类名
     * @param entityUrl   类全名
     * @return   类名
     */
    private String getClassName(String entityUrl){
        Class clazz = Utils.getClazz(entityUrl);
        return clazz.getSimpleName();
    }

    /**
     * get entity codes
     * @param entityUrl  need to input classAllName
     * @return a entity params Map
     */
    private HashMap getEntities(String entityUrl) {
        HashMap hashMap = new HashMap();
        Class clazz = Utils.getClazz(entityUrl);
        // 获取类中所有字段信息,并存入map
        List<Field> fields = Arrays.asList( clazz.getDeclaredFields());
        fields.forEach(
                (field) -> hashMap.put(field.getType().getSimpleName(), field.getName()));

        return hashMap;
    }


    /**
     *  将所有的字段拼接成一个字符串，用于创建构造方法
     * @param attrs 需要拼接的参数
     * @return    拼接好的字段
     */
    private String getColumnsToString(List<Attribute> attrs) {
        StringBuffer stringBuffer = new StringBuffer();
        attrs.forEach(
                (attr) -> stringBuffer.append(attr.getType()+" "+attr.getName()+ ","));
        stringBuffer.deleteCharAt(stringBuffer.length() - 1);
        return stringBuffer.toString();
    }
}
